﻿/*******************************************************************
This file is part of WP7DropBox.

WP7DropBox is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

WP7DropBox is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with WP7DropBox.  If not, see <http://www.gnu.org/licenses/>.
*******************************************************************/
namespace l3v5y.Dropbox
{
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Security.Cryptography;
    using System.Text;
    public class OAuthHelper
    {
        Token app = new Token();
        Token user = new Token()            ;
        public OAuthHelper(Token app, Token user)
        {
            this.app = app;
            this.user = user;
        }
        public OAuthHelper()
        {
        }
        public OAuthHelper(Token app)
        {
            this.app = app;
        }
        /// <summary>
        /// Generates a new nonce, must be unique for each OAuth request
        /// </summary>
        /// <returns>nonce as string</returns>
        public static string nonce()
        {
            return new Random().Next(123400, 9999999).ToString();
        }
        /// <summary>
        /// Gets a timestamp in the format required for OAuth
        /// </summary>
        /// <returns>timestamp as string</returns>
        public static string timestamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds).ToString();
        }
        public string ParmsRequestUrl(string url, List<string> userParameters)
        {
            return (url + "?" + string.Join("&", userParameters.ToArray()));
        }
        /// <summary>
        /// Generates a URL with OAuth parameters
        /// </summary>
        /// <param name="url">base URL for request</param>
        /// <param name="userParameters">name/value pairs for parameters</param>
        /// <param name="mode">GET or POST, must match HTTP method used</param>
        /// <returns>OAuth compatible URL</returns>
        public string OAuthRequestUrl(string url, List<string> userParameters, string mode = "GET")
        {
            List<string> Parameters = userParameters;
            Parameters.Add("oauth_consumer_key=" + HttpUtility.UrlEncode(app.token));
            Parameters.Add("oauth_nonce=" + HttpUtility.UrlEncode(nonce()));
            Parameters.Add("oauth_signature_method=HMAC-SHA1");
            Parameters.Add("oauth_version=1.0");
            Parameters.Add("oauth_callback=oob");
            Parameters.Add("oauth_timestamp=" + HttpUtility.UrlEncode(timestamp()));
            if (user != null)
            {
                Parameters.Add("oauth_token=" + user.token);
            }
            Parameters.Sort();

            string parametersStr = string.Join("&", Parameters.ToArray());

            string baseStr = mode + "&" +
                 HttpUtility.UrlEncode(url).Replace("%2f", "%2F").Replace("%3a", "%3A").Replace("%3d", "%3D") + "&" +
                 HttpUtility.UrlEncode(parametersStr).Replace("%2f", "%2F").Replace("%3a", "%3A").Replace("%3d", "%3D");


            /* create the crypto class we use to generate a signature for the request */
            byte[] key = Encoding.UTF8.GetBytes(app.secret);
            if (user != null)
            {
                key = Encoding.UTF8.GetBytes(app.secret + "&" + user.secret);
            }

            HMACSHA1 sha1 = new HMACSHA1(key);

            /*
             * byte[] key = Encoding.UTF8.GetBytes(VAL_OAUTHCONSUMERSECRET + "&" +
                                    requestSecret);
             * */
            /* generate the signature and add it to our parameters */
            byte[] baseStringBytes = Encoding.UTF8.GetBytes(baseStr);
            byte[] baseStringHash = sha1.ComputeHash(baseStringBytes);
            String base64StringHash = Convert.ToBase64String(baseStringHash);
            String encBase64StringHash = HttpUtility.UrlEncode(base64StringHash);
            Parameters.Add("oauth_signature=" + encBase64StringHash);
            Parameters.Sort();
            return (url + "?" + string.Join("&", Parameters.ToArray()));
        }
    }
}
